package com.ml.mall.service.company.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ml.mall.bean.base.ApiRestResult;
import com.ml.mall.bean.page.Page;
import com.ml.mall.bean.req.company.*;
import com.ml.mall.bean.res.company.*;
import com.ml.mall.consts.CommonConsts;
import com.ml.mall.consts.RoleIDConst;
import com.ml.mall.consts.UserConsts;
import com.ml.mall.entity.company.*;
import com.ml.mall.entity.country.CountryStates;
import com.ml.mall.entity.sys.SysUser;
import com.ml.mall.enums.CommonEnum;
import com.ml.mall.enums.RedisUtilsCacheEnum;
import com.ml.mall.enums.RetStatusNum;
import com.ml.mall.enums.SysSeqNameEnum;
import com.ml.mall.exception.BizException;
import com.ml.mall.mapper.SysCompanyRemarkMapper;
import com.ml.mall.mapper.company.*;
import com.ml.mall.mapper.sys.SysUserMapper;
import com.ml.mall.security.JwtUtil;
import com.ml.mall.service.common.CommonSeqService;
import com.ml.mall.service.company.*;
import com.ml.mall.service.asyn.AuthMailServiceImplAsyn;
import com.ml.mall.service.country.CountryStatesService;
import com.ml.mall.service.remark.SysRemarkService;
import com.ml.mall.service.sys.SysSubscriptionService;
import com.ml.mall.service.sys.SysUserService;
import com.ml.mall.utils.HttpUtil;
import com.ml.mall.utils.MD5;
import com.ml.mall.utils.RedisUtil;
import com.ml.mall.utils.StrUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysCompanyServiceImpl extends ServiceImpl<SysCompanyMapper, SysCompany> implements SysCompanyService {

    @Autowired
    private CommonSeqService commonSeqService;
    @Autowired
    private SysCompanyMapper sysCompanyMapper;
    @Autowired
    private SysCompanyAddrMapper sysCompanyAddrMapper;
    @Autowired
    private SysCompanyInterestIndustryMapper sysCompanyInterestIndustryMapper;
    @Autowired
    private SysCompanyBusinessBackgroundMapper sysCompanyBusinessBackgroundMapper;
    @Autowired
    private SysCompanyBankMapper sysCompanyBankMapper;
    @Autowired
    private SysCompanyShippingMapper sysCompanyShippingMapper;
    @Autowired
    private SysCompanyLogisticsInfoMapper sysCompanyLogisticsInfoMapper;

    @Autowired
    private SysCompanySsmPicMapper sysCompanySsmPicMapper;
    @Autowired
    private SysCompanyReasonMapper sysCompanyReasonMapper;

    @Autowired
    private SysCompanyRegistAccMapper sysCompanyRegistAccMapper;

    @Autowired
    private SysUserCompanyRelationMapper sysUserCompanyRelationMapper;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysCompanySsmPicService sysCompanySsmPicService;

    @Autowired
    private SysCompanyShippingService sysCompanyShippingService;
    @Autowired
    private SysCompanyBankService sysCompanyBankService;
    @Autowired
    private SysCompanyAddrService sysCompanyAddrService;
    @Autowired
    private SysCompanyLogisticsInfoService sysCompanyLogisticsInfoService;

    @Autowired
    private SysCompanyRemarkMapper sysCompanyRemarkMapper;

    @Autowired
    private CountryStatesService countryStatesService;

    @Lazy
    @Autowired
    private AuthMailServiceImplAsyn authMailServiceAsyn;

    @Autowired
    private SysCompanyInterestIndustryService sysCompanyInterestIndustryService;

    @Autowired
    private SysCompanyReasonService sysCompanyReasonService;

    @Autowired
    private SysCompanyBusinessBackgroundService sysCompanyBusinessBackgroundService;

    @Autowired
    private SysUserCompanyRelationService sysUserCompanyRelationService;

    @Autowired
    private SysSubscriptionService sysSubscriptionService;

    @Autowired
    private SysRemarkService sysRemarkService;

    @Override
    public ApiRestResult queryCompanyByType() {
        sysCompanyMapper.selectAllCompanyByType(2);
        return null;
    }

    @Transactional
    @Override
    public ApiRestResult createCompany(CompanyNewDto dto) {
        //校测参数
        sysCompanyInterestIndustryService.checkInterestedIndustry(dto.getInterestedIndustryObj(), dto.getCompanyType());
        // 校验注册码
//        checkRegistartionNo(dto.getRegistartionNo());
        //检验物流信息
        sysCompanyLogisticsInfoService.checkLogisticsInfo(dto.getLogisticsInfo());

        //如果邮件地址已被其他公司使用，抛出异常
        if(dto.getBillAddr() != null){
            checkEmail(dto.getBillAddr().getEmail(), null);
        }

        Long companyId = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_COMPANY_ID.getCode());
        Long companyInvite = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_COMPANY_INVITE.getCode(), 0);

        String statesCanSendArr = "-";  //可配送洲属数组
        // 添加配送州属信息
        if (dto.getCompanyType().equals(CommonConsts.ROLE_TYPE_SUPPLIER) && dto.getCompanyShipping() != null) {
            List<Long> statesArr = dto.getCompanyShipping().getStatesArr();
            //洲属名特殊拼接 用于商品搜索
            if (null != statesArr && statesArr.size() > 0) {
                for (Long stateId : statesArr) {
                    statesCanSendArr = statesCanSendArr + stateId + "-";
                }
            }
            sysCompanyShippingService.saveSupplierShipping(dto.getCompanyShipping(), companyId);
        }

        // 添加物流信息
        sysCompanyLogisticsInfoService.saveSupplierLogistics(dto.getLogisticsInfo(), companyId);

        // 添加公司信息
        SysCompany sysCompany = new SysCompany();
        BeanUtils.copyProperties(dto, sysCompany);
        sysCompany.setCompanyId(companyId);
        sysCompany.setState(CommonConsts.FIXED_NUM_ZERO);
        sysCompany.setInviteCode("SP" + companyInvite);
        sysCompany.setIsVerify(CommonConsts.COMPANY_INFO_IS_NOT_VERIFIED);
        sysCompany.setNeedPay(CommonConsts.NEED_PAY);
        //公司创建时使用id最小的配套
        Long initialSubscriptionId = sysSubscriptionService.queryInitialSubscriptionId(sysCompany.getCompanyType());
        sysCompany.setSubType(initialSubscriptionId.intValue());
        //从购物/仓库地址获取州属id
        if(dto.getShopAddr() != null && dto.getShopAddr().getStates() != null){
            sysCompany.setStatesId(dto.getShopAddr().getStates().intValue());
        }
        //从账单地址获取邮件地址
        if (dto.getBillAddr() != null) {
            sysCompany.setEmailAddress(dto.getBillAddr().getEmail());
        }
        sysCompany.setStatesCanSend(statesCanSendArr); //设置可配送洲属数组
        sysCompanyMapper.insert(sysCompany);

        // 添加感兴趣的产业
        sysCompanyInterestIndustryService.insertBatch(companyId, dto.getInterestedIndustryObj());

        //添加公司SSM图片
        sysCompanySsmPicService.saveCompanySsmPics(dto.getCompanySsmPicArr(), companyId);

        //增加注册原因
        sysCompanyReasonService.saveCompanyReason(dto.getRegistrationReason(), companyId);

        // 添加业务描述
        sysCompanyBusinessBackgroundService.saveCompanyBusinessBackground(dto.getBusinessBackground(), companyId);

        // 添加银行卡信息
        sysCompanyBankService.saveCompanyBankService(dto.getBankDetails(), companyId);

        //添加公司地址
        sysCompanyAddrService.saveCompanyAddr(dto.getBillAddr(), dto.getShopAddr(), companyId);

        //发送邮件  修改为注册时发送
//        authMailServiceAsyn.registeCompanyEmailAsyn(JwtUtil.getCurrentUser(),dto,companyId);

        return ApiRestResult.ok();
    }

    /**
     * 检查邮件地址
     * @param email
     * @param companyId
     */
    private void checkEmail(String email, Long companyId) {
        //邮件地址被其他公司使用时，抛出异常
        if(email != null){
            SysCompany dbCompany = sysCompanyMapper.selectByEmail(email);
            if(dbCompany != null && !dbCompany.getCompanyId().equals(companyId)){
                throw new BizException(CommonEnum.MAILBOX_HAS_BEEN_REGISTERED);
            }
        }
    }

    @Transactional
    @Override
    public ApiRestResult editCompany(CompanyEditDto dto) {
        //检查字段
        //非管理员只能修改自己公司的信息
        SysUser currentUser = JwtUtil.getCurrentUser();
        SysCompany dbSysCompany;
        if (CommonConsts.ROLE_TYPE_ADMIN.equals(currentUser.getRoleType())) {
            dbSysCompany = sysCompanyMapper.selectById(dto.getId());
        } else {
            dbSysCompany = sysCompanyMapper.selectByCompanyId(currentUser.getCompanyId());
            dto.setId(dbSysCompany.getId());
            //非管理员不可更改公司状态
            dto.setState(dbSysCompany.getState());
            //非管理员不可更改拒绝信息
            dto.setRefuseReason(dbSysCompany.getRefuseReason());
            //非管理员不可更改公司配套
            dto.setSubType(dbSysCompany.getSubType());
        }

        if (null == dbSysCompany) {
            throw new BizException(CommonEnum.COMPANY_IS_NOT_EXIST);
        }
        //检测配套是否更改 更改则发送邮件通知该公司用户
        if(!CommonConsts.ROLE_TYPE_ADMIN.equals(dbSysCompany.getCompanyType()) && !CommonConsts.ROLE_TYPE_PARTNER.equals(dbSysCompany.getCompanyType())){
            checkSubType(dto,dbSysCompany);
        }

        //校验注册码
//        checkRegistartionNo(dto.getRegistartionNo());

        //检查邮箱
        if(null != dto.getBillAddr()){
            checkEmail(dto.getBillAddr().getEmail(), dbSysCompany.getCompanyId());
        }



        //检查买家是否选择了感兴趣产业
        sysCompanyInterestIndustryService.checkInterestedIndustry(dto.getInterestIndustryObj(), dbSysCompany.getCompanyType());
        //检查买家与卖家是否填写了业务类型
        checkTypesBusiness(dto.getTypesBusiness(), dbSysCompany.getCompanyType());
        //检查是否买家与卖家是否选择了产业类型
        checkIndustry(dto.getIndustryId(), dbSysCompany.getCompanyType());
        //检查物流信息
        sysCompanyLogisticsInfoService.checkLogisticsInfo(dto.getLogisticsInfo());

        // 修改公司信息
        SysCompany sysCompany = new SysCompany();
        BeanUtils.copyProperties(dto, sysCompany);
        //从购物/仓库地址获取州属id
        if(dto.getShopAddr() != null && dto.getShopAddr().getStates() != null){
            sysCompany.setStatesId(dto.getShopAddr().getStates().intValue());
        }
        //从账单地址中获取邮件地址
        if (dto.getBillAddr() != null) {
            sysCompany.setEmailAddress(dto.getBillAddr().getEmail());
        }

        if (CommonConsts.STATE_PENDING.equals(dbSysCompany.getState()) || CommonConsts.STATE_REFUSE.equals(dbSysCompany.getState())){
            if(CommonConsts.STATE_NORMAL.equals(dto.getState())){
                //创建账号
                creatrCompanyAcc(dbSysCompany);
            }
        }
        //如果是修改为拒绝
        if(null != dto.getState()
                && dto.getState().equals(CommonConsts.STATE_REFUSE)
                && currentUser.getRoleType().equals(CommonConsts.ROLE_TYPE_ADMIN)){
            //存储拒绝记录
            sysRemarkService.addCompanyRefuseRecord(dbSysCompany.getCompanyId(), dto.getRefuseReason());
        }
        sysCompanyMapper.updateById(sysCompany);

        // 添加业务描述
        if (!StrUtil.isBlank(dto.getBusinessBackground())) {
            SysCompanyBusinessBackground sysCompanyBusinessBackground = new SysCompanyBusinessBackground();
            sysCompanyBusinessBackground.setCompanyId(dbSysCompany.getCompanyId());
            sysCompanyBusinessBackground.setDescription(dto.getBusinessBackground());

            if (!existsDataWithCompanyId(sysCompanyBusinessBackgroundMapper, dbSysCompany.getCompanyId())) {
                sysCompanyBusinessBackgroundMapper.insert(sysCompanyBusinessBackground);
            } else {
                sysCompanyBusinessBackgroundMapper.updateByCompanyId(sysCompanyBusinessBackground);
            }
        }

        // 修改银行卡信息
        if (dto.getBankDetails() != null) {
            SysCompanyBank sysCompanyBank = new SysCompanyBank();
            BeanUtils.copyProperties(dto.getBankDetails(), sysCompanyBank);

            QueryWrapper<SysCompanyBank> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("company_id", dbSysCompany.getCompanyId());

            if (null != sysCompanyBankService.getOne(queryWrapper)) {
                sysCompanyBankService.update(sysCompanyBank, queryWrapper);
            } else {
                sysCompanyBank.setCompanyId(dbSysCompany.getCompanyId());
                sysCompanyBankMapper.insert(sysCompanyBank);
            }
        }


        // 修改账单地址
        if (dto.getBillAddr() != null) {
            log.info("companyAddrEditDto==={}", dto.getBillAddr());
            SysCompanyAddr billAddr = new SysCompanyAddr();
            BeanUtils.copyProperties(dto.getBillAddr(), billAddr);

            QueryWrapper<SysCompanyAddr> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("company_id", dbSysCompany.getCompanyId());
            queryWrapper.eq("type", CommonConsts.COMPANY_ADDR_TYPE_BILL);

            if (null != sysCompanyAddrService.getOne(queryWrapper)) {
                sysCompanyAddrMapper.update(billAddr, queryWrapper);
            } else {
                billAddr.setCompanyId(dbSysCompany.getCompanyId());
                billAddr.setType(CommonConsts.COMPANY_ADDR_TYPE_BILL);
                sysCompanyAddrService.save(billAddr);
            }
        }

        // 修改购物地址
        if (dto.getShopAddr() != null) {
            log.info("shopAddr==={}", dto.getShopAddr());
            SysCompanyAddr shopAddr = new SysCompanyAddr();
            BeanUtils.copyProperties(dto.getShopAddr(), shopAddr);

            QueryWrapper<SysCompanyAddr> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("company_id", dbSysCompany.getCompanyId());
            queryWrapper.eq("type", CommonConsts.COMPANY_ADDR_TYPE_SHOP);

            if (null != sysCompanyAddrService.getOne(queryWrapper)) {
                sysCompanyAddrService.update(shopAddr, queryWrapper);
            } else {
                shopAddr.setCompanyId(dbSysCompany.getCompanyId());
                shopAddr.setType(CommonConsts.COMPANY_ADDR_TYPE_SHOP);
                sysCompanyAddrService.save(shopAddr);
            }
        }

        // 修改感兴趣的产业
        if (dto.getInterestIndustryObj() != null) {
            sysCompanyInterestIndustryService.removeByCompanyId(dbSysCompany.getCompanyId());
            sysCompanyInterestIndustryService.insertBatch(dbSysCompany.getCompanyId(), dto.getInterestIndustryObj());
        }

        //修改供应商物流信息
        sysCompanyLogisticsInfoService.editSupplierLogistics(dto.getLogisticsInfo(), dto.getCompanyShipping(), dbSysCompany.getCompanyId());

        //根据公司状态修改用户状态
        updateAccStateByCompanyState(dbSysCompany.getCompanyId(), dto.getState());

        //发送邮件
        dbSysCompany.setRefuseReason(dto.getRefuseReason());
        authMailServiceAsyn.editCompanyEmailCompany(dbSysCompany, dto.getState());

        return ApiRestResult.ok();
    }

    private void checkSubType(CompanyEditDto dto, SysCompany dbSysCompany) {
        if(null != dto.getSubType() && !dto.getSubType().equals(dbSysCompany.getSubType())){
            authMailServiceAsyn.editCompanySubType(dto,dbSysCompany);
        }
    }

    /**
     * 根据公司状态修改用户状态
     *
     * @param companyId    公司id
     * @param companyState 公司状态
     */
    private void updateAccStateByCompanyState(Long companyId, Integer companyState) {
        Integer userState = CommonConsts.STATE_NORMAL.equals(companyState) ? CommonConsts.USER_STATE_OK
                : CommonConsts.STATE_FORBI.equals(companyState) ? CommonConsts.USER_STATE_FORBID
                : null;

        if (null != userState) {
            sysUserMapper.updateAccState(companyId, userState);
        }
    }

    /**
     * 通过companyId查询是否存在对应数据
     *
     * @param baseMapper 用于进行查询的mapper
     * @param companyId
     * @return
     */
    private <T> boolean existsDataWithCompanyId(BaseMapper<T> baseMapper, Long companyId) {
        QueryWrapper<T> queryWrapper = new QueryWrapper();
        queryWrapper.eq("company_id", companyId);
        return baseMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 检查公司产业
     *
     * @param industryId
     * @param companyType
     */
    private void checkIndustry(Long industryId, Integer companyType) {
        if (CommonConsts.ROLE_TYPE_PURCHASE.equals(companyType) || CommonConsts.ROLE_TYPE_SUPPLIER.equals(companyType)) {
            if (null == industryId) {
                throw new BizException(CommonEnum.COMPANY_INDUSTRY_IS_NULL);
            }
        }
    }

    /**
     * 检查注册码
     *
     * @param registartionNo
     */
    private void checkRegistartionNo(String registartionNo) {
        if (!StringUtils.isEmpty(registartionNo)) {
            int count = sysCompanyMapper.selectCountByInviteCode(registartionNo);
            if (count < 1) {
                throw new BizException(CommonEnum.INVITE_CODE_INVALID);
            }
        }
    }

    /**
     * 检查公司业务类型
     *
     * @param typesBusiness
     * @param companyType
     */
    private void checkTypesBusiness(String typesBusiness, Integer companyType) {
        if (CommonConsts.ROLE_TYPE_SUPPLIER.equals(companyType)
                || CommonConsts.ROLE_TYPE_PURCHASE.equals(companyType)) {
            if (StringUtils.isEmpty(typesBusiness)) {
                throw new BizException(CommonEnum.COMPANY_TYPES_BUSINESS_NULL);
            }
        }
    }

    @Override
    public CompanyQueryInfoRes queryOneCompany(CompanyDto dto) {
        // SysUser currentUser = JwtUtil.getCurrentUser();
//        // 管理员和合作伙伴可以查询到所有公司信息。其他公司只能查到自己公司信息
//        if(!CommonConsts.ROLE_TYPE_ADMIN.equals(currentUser.getRoleType()) && !CommonConsts.ROLE_TYPE_PARTNER.equals(currentUser.getRoleType())){
//            dto.setCompanyId(currentUser.getCompanyId());
//        }
        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dto.getId() != null, SysCompany::getId, dto.getId());
        wrapper.eq(dto.getCompanyId() != null, SysCompany::getCompanyId, dto.getCompanyId());
        if (dto.getId() == null && dto.getCompanyId() == null) {
            return null;
        }
        SysCompany sysCompany = sysCompanyMapper.selectOne(wrapper);

        if (sysCompany == null) {
            return null;
        }

        CompanyQueryInfoRes companyQueryInfoRes = new CompanyQueryInfoRes();
        BeanUtils.copyProperties(sysCompany, companyQueryInfoRes);

        SysCompanyBusinessBackground sysCompanyBusinessBackground = sysCompanyBusinessBackgroundMapper.selectByCompanyId(sysCompany.getCompanyId());
        if (sysCompanyBusinessBackground != null) {
            companyQueryInfoRes.setBusinessBackground(sysCompanyBusinessBackground.getDescription());
        }
        //获取公司感兴趣的产业信息
        List<SysCompanyInterestIndustry> sysCompanyInterestIndustryList = sysCompanyInterestIndustryMapper.selectByCompanyId(sysCompany.getCompanyId());
        CompanyInterestIndustryRes companyInterestIndustryRes = new CompanyInterestIndustryRes();
        BeanUtils.copyProperties(sysCompany, companyInterestIndustryRes);
        List<Long> interestIndustryIds = new ArrayList<>();
        companyInterestIndustryRes.setInterestedIdArr(interestIndustryIds);
        for (SysCompanyInterestIndustry sysCompanyInterestIndustry : sysCompanyInterestIndustryList) {
            interestIndustryIds.add(sysCompanyInterestIndustry.getIndustryId());
            if (CommonConsts.INDUSTRY_OTHER.equals(sysCompanyInterestIndustry.getIndustryId())) {
                companyInterestIndustryRes.setOtherName(sysCompanyInterestIndustry.getIndustryOther());
            }
        }
        companyQueryInfoRes.setInterestIndustryObj(companyInterestIndustryRes);

        //获取账单地址及收货地址
        List<SysCompanyAddr> sysCompanyAddrList = sysCompanyAddrMapper.selectByCompanyId(sysCompany.getCompanyId());
        for (SysCompanyAddr addr : sysCompanyAddrList) {
            CompanyAddrDto companyAddrDto = new CompanyAddrDto();
            BeanUtils.copyProperties(addr, companyAddrDto);
            companyAddrDto.setCountry(addr.getCountry());
            CountryStates states = countryStatesService.getById(addr.getStates());
            companyAddrDto.setStatesName(states == null ? "" : states.getStatesName());
            if (CommonConsts.FIXED_NUM_ZERO.equals(addr.getType())) {
                companyQueryInfoRes.setBillAddr(companyAddrDto);
            }
            if (CommonConsts.FIXED_NUM_ONE.equals(addr.getType())) {
                companyQueryInfoRes.setShopAddr(companyAddrDto);
            }
        }
        SysCompanyBank sysCompanyBank = sysCompanyBankMapper.selectByCompanyId(sysCompany.getCompanyId());
        if (sysCompanyBank != null) {
            BeanUtils.copyProperties(sysCompanyBank, companyQueryInfoRes.getBankDetails());
        }

        SysCompanyShipping sysCompanyShipping = sysCompanyShippingMapper.selectByCompanyId(sysCompany.getCompanyId());
        if (null != sysCompanyShipping) {
            CompanyShippingRes companyShippingRes = new CompanyShippingRes();
            companyShippingRes.setId(sysCompanyShipping.getId());
            companyShippingRes.setCountryId(sysCompanyShipping.getCompanyId());
            String str = sysCompanyShipping.getStatesArr();
            List<String> statesStrArr = (null == str ? new ArrayList<>() : StrUtils.getListByStr(str));
            List<Long> statesArr = statesStrArr.stream()
                    .map(statesStr -> StringUtils.replace(statesStr, " ", ""))
                    .filter(statesStr -> !StringUtils.isEmpty(statesStr))
                    .map(Long::valueOf)
                    .collect(Collectors.toList());
            companyShippingRes.setStatesArr(statesArr);
            companyQueryInfoRes.setCompanyShipping(companyShippingRes);
        }


        SysCompanyLogisticsInfo sysCompanyLogisticsInfo = sysCompanyLogisticsInfoMapper.selectByCompanyId(sysCompany.getCompanyId());
        if (sysCompanyLogisticsInfo != null) {
            BeanUtils.copyProperties(sysCompanyLogisticsInfo, companyQueryInfoRes.getLogisticsInfo());
        }

        //查询全部ssm图片
        QueryWrapper<SysCompanySsmPic> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id", dto.getCompanyId());
        List<SysCompanySsmPic> companySsmPicArr = sysCompanySsmPicMapper.selectList(queryWrapper);
        companyQueryInfoRes.setCompanySsmPicArr(companySsmPicArr);

        return companyQueryInfoRes;
    }

    @Override
    public Page<CompanyQueryRes> queryPageCompany(CompanyQueryDto dto) {
        SysUser sysUser = JwtUtil.getCurrentUser();
        //如果是合作商
        if (sysUser.getRoleType().equals(CommonConsts.ROLE_TYPE_PARTNER)) {
            //仅能查询自己下属商户；
            SysCompany sysCompany = sysCompanyMapper.selectByCompanyId(sysUser.getCompanyId());
            dto.setInviteCode(sysCompany.getInviteCode());
        }
        Page<CompanyQueryRes> page = new Page<>(dto.getPageIndex(), dto.getPageNum());
        if (!StringUtils.hasText(dto.getOrderBy())) {
            dto.setOrderBy("`id`");
        }
        List<CompanyQueryRes> companyQueryResList = sysCompanyMapper.selectPageCompany(dto);
        Long count = sysCompanyMapper.countCompany(dto);
        page.setRecords(companyQueryResList);
        page.setTotal(count.intValue());
        return page;
    }

    // @Transactional
    @Override
    public ApiRestResult registerCompany(CompanyRegisterDto dto) {
        //买家，卖家检验验证码和产业类型
        if(CommonConsts.ROLE_TYPE_PURCHASE.equals(dto.getCompanyType())
            || CommonConsts.ROLE_TYPE_SUPPLIER.equals(dto.getCompanyType())){
            if(null == dto.getIndustryId()){
                throw new BizException(CommonEnum.COMPANY_INDUSTRY_IS_NULL);
            }

            if(StrUtil.isBlank(dto.getCaptchaCode())){
                throw new BizException(CommonEnum.CAPTCHA_IS_BLANK);
            }

            Boolean isSamePic = verifyCaptchaCode(dto.getCaptchaCode(), HttpUtil.getIp());
            log.info("isSamePic==222={}", isSamePic);
            if (!isSamePic) {
                return ApiRestResult.err(RetStatusNum.ERR_CAPTCHA_CODE.getMessage(), RetStatusNum.ERR_CAPTCHA_CODE.getCode());
            }
            log.info("isSamePic==={}", isSamePic);
        }

        //检验邮箱，防止账户冲突
        String emailAddress = dto.getEmailAddress();
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getAcc, emailAddress);
        Integer accCount = sysUserMapper.selectCount(queryWrapper);
        if (accCount > 0) {
            throw new BizException(CommonEnum.MAILBOX_HAS_BEEN_REGISTERED);
        }

        //检测公司类型是否正确
        if(CommonConsts.ROLE_TYPE_ADMIN.equals(dto.getCompanyType())){
            throw new BizException(CommonEnum.WRONG_TYPE_OF_REGISTERED_COMPANY);
        }

        //如果数据库中已有注册邮箱对应的公司数据，只发送通知邮件
        SysCompany dbCompany = sysCompanyMapper.selectByEmail(emailAddress);
        String companyName = null;
        if (null == dbCompany) {
            //存储注册信息
            this.saveRegisterData(dto);
            companyName = dto.getCompanyName();
        }else{
            companyName = dbCompany.getCompanyName();
        }

        //注册公司发送邮件
        log.info("dto.getSysCompanyRegistAcc().getEmail()==={}", emailAddress);
        authMailServiceAsyn.registeCompanyEmailAsyn(companyName, emailAddress);

        return ApiRestResult.ok();
    }

    @Override
    public void saveCodeToRedis(String code, String ip) {
        redisUtil.set(RedisUtilsCacheEnum.REDIS_KEY_CAPTCHA.getKeyPrefix() + ip, code, RedisUtilsCacheEnum.REDIS_KEY_CAPTCHA.getExpiresSecond());
    }

    public Boolean verifyCaptchaCode(String code, String ip) {
        String codeStr = String.valueOf(redisUtil.get(RedisUtilsCacheEnum.REDIS_KEY_CAPTCHA.getKeyPrefix() + ip));
        log.info("code====={}", codeStr);
        if (code.equalsIgnoreCase(codeStr)) {
            redisUtil.del(RedisUtilsCacheEnum.REDIS_KEY_CAPTCHA.getKeyPrefix() + ip);
            return true;
        }
        return false;
    }

    @Override
    public void companyRegisterSendVerificCode(CompanySendVerificCode dto) {
        String ip = HttpUtil.getIp();
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        String code = lineCaptcha.getCode();
        redisUtil.set(RedisUtilsCacheEnum.REDIS_KEY_CAPTCHA.getKeyPrefix() + ip, code, RedisUtilsCacheEnum.REDIS_KEY_CAPTCHA.getExpiresSecond());
        authMailServiceAsyn.companyRegisterSendVerificCodeMailAsyn(code, dto);
    }

    @Override
    @Transactional
    public int deleteByBatchCompanyIds(List<Long> ids) {
        int i = 0;
        LambdaQueryWrapper<SysCompany> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysCompany::getId, ids)
                .select(SysCompany::getCompanyId);
        List<SysCompany> companies = sysCompanyMapper.selectList(queryWrapper);
        List<Long> companyIds = companies.stream()
                .map(SysCompany::getCompanyId)
                .collect(Collectors.toList());
        //同时删除公司信息及其地址信息，感兴趣产业信息，背景信息，银行信息
        // 删除公司的州属信息，物流信息和证书图片，注册原因,注册账户信息
        // 解除用户与公司间的关联
        QueryWrapper deleteWrapper = new QueryWrapper();
        deleteWrapper.in("company_id", companyIds);
        i = sysCompanyMapper.delete(deleteWrapper);
        sysCompanyAddrMapper.delete(deleteWrapper);
        sysCompanyInterestIndustryMapper.delete(deleteWrapper);
        sysCompanyBusinessBackgroundMapper.delete(deleteWrapper);
        sysCompanyBankMapper.delete(deleteWrapper);
        sysCompanyShippingMapper.delete(deleteWrapper);
        sysCompanyLogisticsInfoMapper.delete(deleteWrapper);
        sysCompanySsmPicMapper.delete(deleteWrapper);
        sysCompanyReasonMapper.delete(deleteWrapper);
        sysCompanyRegistAccMapper.delete(deleteWrapper);
        sysUserCompanyRelationMapper.delete(deleteWrapper);
        return i;
    }

    @Override
    public Integer getCompanySupplierOfStep() {
        SysUser currentUser = JwtUtil.getCurrentUser();
        //卖家状态
        if (currentUser != null && currentUser.getRoleType() == CommonConsts.ROLE_TYPE_SUPPLIER) {
            Long count = sysCompanyMapper.querySupplierVariantNum(currentUser.getCompanyId());
            if (count > 0) {
                return 2;
            } else {
                return 1;
            }
        }
        return -1;
    }

    /**
     * 验证验证码正确之后存储注册消息
     *
     * @param dto
     * @return void
     * @author Daizh
     * @date 2021/6/21 17:28
     */
    @Transactional
    public void saveRegisterData(CompanyRegisterDto dto) {
        //此处校验 邀请码
        if (dto.getCompanyType().equals(CommonConsts.ROLE_TYPE_SUPPLIER)) {
            //检验 邀请码是否正确；
        }
        //添加邀请码
        Long companyInvite = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_COMPANY_INVITE.getCode(), 0);
        // 添加公司信息
        SysCompany sysCompany = new SysCompany();
        BeanUtils.copyProperties(dto, sysCompany);
        sysCompany.setInviteCode("SP" + companyInvite);
        sysCompany.setCompanyId(commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_COMPANY_ID.getCode()));
        sysCompany.setState(CommonConsts.STATE_PENDING);
        sysCompany.setIsVerify(CommonConsts.COMPANY_INFO_IS_NOT_VERIFIED);
        sysCompany.setNeedPay(CommonConsts.NEED_PAY);
        //公司注册使用最小配套
        if(CommonConsts.ROLE_TYPE_SUPPLIER.equals(sysCompany.getCompanyType()) || CommonConsts.ROLE_TYPE_PURCHASE.equals(sysCompany.getCompanyType())){
            Long initialSubscriptionId = sysSubscriptionService.queryInitialSubscriptionId(sysCompany.getCompanyType());
            sysCompany.setSubType(initialSubscriptionId.intValue());
        }
        sysCompanyMapper.insert(sysCompany);
        //公司注册后进入软删除状态
        sysCompanyMapper.deleteById(sysCompany.getId());
        // 添加公司感兴趣产业
        List<Long> interestedIndustryIds = dto.getInterestedIndustry();
        if (dto.getCompanyType().equals(CommonConsts.ROLE_TYPE_PURCHASE) && interestedIndustryIds != null && interestedIndustryIds.size() > 0) {
            sysCompanyInterestIndustryMapper.insertBatch(sysCompany.getCompanyId(), interestedIndustryIds);
        }
        // 添加公司描述
        SysCompanyBusinessBackground businessBackground = new SysCompanyBusinessBackground();
        businessBackground.setCompanyId(sysCompany.getCompanyId());
        businessBackground.setDescription(dto.getBackground());
        sysCompanyBusinessBackgroundMapper.insert(businessBackground);

        //添加账号信息
        if (dto.getSysCompanyRegistAcc() != null) {
            SysCompanyRegistAcc obj = new SysCompanyRegistAcc();
            BeanUtils.copyProperties(dto.getSysCompanyRegistAcc(), obj);
            obj.setCompanyId(sysCompany.getCompanyId());
            obj.setEmail(dto.getEmailAddress());
            sysCompanyRegistAccMapper.insert(obj);
        }

    }

    /**
     * 创建公司账号
     *
     * @param dto
     * @return void
     * @author Daizh
     * @date 2021/6/22 15:43
     */
    @Transactional
    public void creatrCompanyAcc(SysCompany dbCompany) {
        //为公司创建账号
        QueryWrapper<SysCompanyRegistAcc> queryWrapper = new QueryWrapper();
        queryWrapper.eq("company_id", dbCompany.getCompanyId());
        SysCompanyRegistAcc sysCompanyRegistAcc = sysCompanyRegistAccMapper.selectOne(queryWrapper);
        if (sysCompanyRegistAcc != null) {
            SysUser sysUser = new SysUser();
            sysUser.setAcc(sysCompanyRegistAcc.getEmail());
            sysUser.setEmail(sysCompanyRegistAcc.getEmail());
            sysUser.setLastName(sysCompanyRegistAcc.getLastName());
            sysUser.setName(sysCompanyRegistAcc.getFirstName());
            sysUser.setCompanyId(dbCompany.getCompanyId());
            sysUser.setTelNumber(dbCompany.getPhoneNo());
            //计算pwd
            String salt = StrUtils.getUUID();
            sysUser.setPwd(MD5.md5(sysCompanyRegistAcc.getPwd(), salt));
            sysUser.setSalt(salt);
            sysUser.setState(UserConsts.NORMAL_STATE); //账号状态暂时直接正常
            log.info("dbCompany.getCompanyType==={}", dbCompany.getCompanyType());
            if (dbCompany.getCompanyType().equals(CommonConsts.ROLE_TYPE_SUPPLIER)) {
                sysUser.setRoleType(CommonConsts.ROLE_TYPE_SUPPLIER); //权限类型
                sysUser.setRoleId(RoleIDConst.SUPPLIER_ADMIN);   //对应公司的管理员角色
            } else if (dbCompany.getCompanyType().equals(CommonConsts.ROLE_TYPE_PURCHASE)){
                sysUser.setRoleType(CommonConsts.ROLE_TYPE_PURCHASE);
                sysUser.setRoleId(RoleIDConst.PURCHASE_ADMIN);
            } else if (dbCompany.getCompanyType().equals(CommonConsts.ROLE_TYPE_PARTNER)){
                sysUser.setRoleType(CommonConsts.ROLE_TYPE_PARTNER);
                sysUser.setRoleId(RoleIDConst.PARTNER_ADMIN);
            }
            sysUserService.saveUserAndRoleUser(sysUser);
            //添加公司用户关联信息
            sysUserCompanyRelationService.addUCRelation(sysUser, dbCompany);
        }
    }


    /**
     * 查询当前账号的公司信息完整程度
     *
     * @return
     */
    @Override
    public CompanyInfoLevelRes queryInfoLevel() {
        CompanyInfoLevelRes res = new CompanyInfoLevelRes();
        // 获取公司信息
        SysUser currentUser = JwtUtil.getCurrentUser();
        Long companyId = currentUser.getCompanyId();

        // 检验完整程度
        // 1. 未完善任何资料
        SysCompany dbCompany = sysCompanyMapper.selectByCompanyId(companyId);
        SysCompanyAddr billAddr = sysCompanyAddrMapper.selectBillAddrByCompanyId(companyId);
        SysCompanyAddr shopAddr = sysCompanyAddrMapper.selectShopAddrByCompanyId(companyId);
        SysCompanyBank companyBank = null;
        if (!CommonConsts.ROLE_TYPE_PURCHASE.equals(dbCompany.getCompanyType())) {
            companyBank = sysCompanyBankMapper.selectByCompanyId(companyId);
        }
        if (!isCompletedBaseInfo(dbCompany)
                || !sysCompanyAddrService.isCompletedAddrInfo(billAddr, dbCompany.getCompanyType())
                || !sysCompanyAddrService.isCompletedAddrInfo(shopAddr, dbCompany.getCompanyType())
                || !sysCompanyBankService.isCompletedBankDetail(companyBank, dbCompany.getCompanyType())) {
            res.setInfoLevel(CommonConsts.COMPANY_INFO_LEVEL_WITHOUT_BASE);
            return res;
        }
        // 2. 填写完公司档案；未完善物流信息；买家；更新买家验证标志
        SysCompanyLogisticsInfo logisticsInfo = sysCompanyLogisticsInfoMapper.selectByCompanyId(companyId);
        SysCompanyShipping companyShipping = sysCompanyShippingMapper.selectByCompanyId(companyId);
        if (!sysCompanyLogisticsInfoService.isCompletedLogisticsInfo(logisticsInfo)
                || !sysCompanyShippingService.isCompletedShippingInfo(companyShipping)
                || CommonConsts.ROLE_TYPE_PURCHASE.equals(dbCompany.getCompanyType())) {

            res.setInfoLevel(CommonConsts.COMPANY_INFO_LEVEL_WITHOUT_LOGISTICS);
            if (CommonConsts.ROLE_TYPE_PURCHASE.equals(dbCompany.getCompanyType())) {
                passInfoVerify(companyId);
            }
            return res;
        }

        // 3. 填写完物流信息；未创建产品
        Long productCount = sysCompanyMapper.countSupplierProduct(companyId);
        log.info("productCount===={}", productCount);
        if (productCount < 1) {
            res.setInfoLevel(CommonConsts.COMPANY_INFO_LEVEL_WITHOUT_PRODUCTS);
            return res;
        }

        // 4. 新卖家鉴定完成，更新卖家验证标志
        res.setInfoLevel(CommonConsts.COMPANY_INFO_LEVEL_COMPLETE);
        passInfoVerify(companyId);
        return res;
    }

    @Override
    public List<CompanyInfoRes> queryCompanyInfoBatch(List<Long> companyList) {
        return sysCompanyMapper.selectCompanyInfoBatch(companyList);
    }

    @Override
    public boolean verify(String emailAddress) {
        SysCompany sysCompany = sysCompanyMapper.selectByEmail(emailAddress);
        if (sysCompany != null) {
            int i = sysCompanyMapper.updateByEmail(emailAddress);
            //异步调用发送邮件
            CompanyRegisterDto dto = new CompanyRegisterDto();
            dto.setCompanyName(sysCompany.getCompanyName());
            dto.setCompanyType(sysCompany.getCompanyType());
            authMailServiceAsyn.registerCompanyEmailAsyn(dto);
            return true;
        }
        return false;
    }

    @Override
    public SysCompany queryByCompanyId(Long companyId) {
        return sysCompanyMapper.selectByCompanyId(companyId);
    }

    /**
     * 公司信息通过验证
     *
     * @param companyId
     */
    private void passInfoVerify(Long companyId) {
        LambdaUpdateWrapper<SysCompany> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysCompany::getIsVerify, CommonConsts.COMPANY_INFO_IS_VERIFIED)
                .eq(SysCompany::getCompanyId, companyId);
        sysCompanyMapper.update(null, updateWrapper);
    }

    /**
     * 判断公司基本信息是否完整
     *
     * @param dbCompany
     * @return
     */
    private boolean isCompletedBaseInfo(SysCompany dbCompany) {
        if (dbCompany == null) {
            return false;
        }
        if (null == dbCompany.getCompanyLevel()
                || StrUtil.isBlank(dbCompany.getTypesBusiness())
                || null == dbCompany.getIndustryId()
                || null == dbCompany.getSubType()) {
            return false;
        }
        return true;
    }
}
